<?php

namespace App\Console\Commands;

use App\Models\Menu;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class GenCode extends Command
{

    // docker exec phpfpm bash -c "cd /code/yoyo-xm2-admin-api && php artisan command:genCode feedback 0"
    // cd /code/mei-laravel && php artisan command:genCode test_user_config

    /** configFile=配置文件名称 ,   override=是否强制重写
     * @var string
     */
    protected $signature = 'command:genCode {configFile=0} {override=0}';  //configPath is  json text file ,

    protected  $description = '自定义代码自动生成';

    private $config = [];


    public function __construct()
    {
        parent::__construct();
    }

    public function handle()
    {
        $configFile = $this->argument('configFile');

        $config =  $this->config = include 'genCodeDir/'.$configFile.'.php';

        $functions = $config['functions'];
        //遍历功能
        foreach($functions as $function){
            switch($function['name']){
                case 'model':
                    $this->genModel($function);
                    break;
                case 'dto':
                    $this->genDto($function);
                    break;
                case 'service':
                    $this->genService($function);
                    break;
                case 'controller':
                    $this->genController($function);
                    break;
                case 'layuiAdminPage':
                    $this->layuiAdminPage($function);
                    break;
                case 'route':
                    $this->genRoute($function);
                    break;
                case 'menu':
                    $this->genMenu($function);
                    break;
            }
        }

    }

    private function writeFile($filePath,$content){

        if(file_exists($filePath) && $this->argument('override') != 1){
            while (true){
                $char = readline("{$filePath} 已经存在,是否重写, y/n:");
                if($char==='n') return false;
                if($char!=='y') {
                    var_dump($char);
                    echo "输入错误\n";
                   continue;
                }
                if($char==='y') break;
            }

        }
        file_put_contents($filePath  , $content);
    }

    private function genModel($function)
    {
        $config  = $this->config;

        $path = $function['path'];
        $namesPace = str_replace('/','\\',ucfirst($path));
        $codeString = view()->file(base_path('genCodeDir/templates/admin/Model.blade.php'),[
            'config'=>$config,
            'namesPace'=>$namesPace,
        ])->render();
        $filePath = $path .  '/' . $config['modelName'] . '.php';
        $this->writeFile($filePath,$codeString);
    }

    private function genDto($function)
    {
        $config  = $this->config;

        $path = $function['path'];

        $namesPace = str_replace('/','\\',ucfirst($path));

        foreach($function['dtoList'] as $dtoName){

            $className  = $config['modelName'] . ucfirst($dtoName);

            $codeString = view()->file(base_path('genCodeDir/templates/admin/DTO.blade.php'),[
                'config'=>$config,
                'namesPace'=>$namesPace,
                'className'=>$className,
            ])->render();

            $filePath = $path .  '/' . $className . '.php';

            $this->writeFile($filePath,$codeString);

        }

    }

    private function genService($function)
    {
        $config  = $this->config;

        $path = $function['path'];

        $namesPace = str_replace('/','\\',ucfirst($path));

        $className  = $config['modelName'] . 'Service';

        $codeString = view()->file(base_path('genCodeDir/templates/admin/Service.blade.php'),[
            'config'=>$config,
            'namesPace'=>$namesPace,
            'className'=>$className,
            'methods'=>$function['methods'],
        ])->render();

        $filePath = $path .  '/' . $className . '.php';

        $this->writeFile($filePath,$codeString);
    }

    private function genController($function)
    {

        $config  = $this->config;

        $path = $function['path'];

        $namesPace = str_replace('/','\\',ucfirst($path));

        $className  = $config['modelName'] . 'Controller';

        $codeString = view()->file(base_path('genCodeDir/templates/admin/Controller.blade.php'),[
            'config'=>$config,
            'namesPace'=>$namesPace,
            'className'=>$className,
            'methods'=>$function['methods'],
        ])->render();

        $filePath = $path .  '/' . $className . '.php';

        $this->writeFile($filePath,$codeString);
    }

    private function layuiAdminPage($function)
    {

        $config  = $this->config;
        $output = str_replace('\\','/',$function['output']);
        if (!file_exists($output)) mkdir($output,0777,1);
        foreach($function['pages'] as $item){
            $page = $item['page'];
            $codeString = view()->file(base_path('genCodeDir/templates/layuiadmin/'.$page.'.blade.php'),[
                'config'=>$config,
                'functions'=>$item['functions'],
            ])->render();
            $this->writeFile($output.'/'.$page.'.html',$codeString);
        }
    }


    private function genRoute($function)
    {
        $lcName = lcfirst($this->config['modelName']);
        $codeString = view()->file(base_path('genCodeDir/templates/admin/Route.blade.php'),[
            'config'=>$this->config,
            'lcName'=>$lcName,
        ])->render();
        $filePath = 'genCodeDir/output/'.$lcName.'.route';
        $basePath = dirname($filePath);
        if(!file_exists($basePath)) mkdir($basePath,0777,1);
        $this->writeFile($filePath,$codeString);
    }

    private function genMenu($function0)
    {
        $config = $this->config;
        $menuPid = $this->config['menuPid'];
        $authority = lcfirst($config['modelName']).':paginate';
        $find = Menu::query()->where('authority',$authority)->first();
        if ($find){
            $parentId = $find->id;
        } else {
            $data = [ //paginate
                'pid'=>$menuPid,
                'title'=>$config['modelShowName'],
                'authority'=>$authority,
                'href'=>'page/'.lcfirst($config['modelName']).'/index.html',
                'icon'=>'fa fa-align-center',
                'is_menu'=>1,
                'status'=>1,
                'created_at'=>now(),
            ];
            $parentId = Menu::query()->insertGetId($data);
        }
        foreach ($function0['functions'] as $function){
            if ($function==='insert'){
                $authority = lcfirst($config['modelName']).':insert';
                $find = Menu::query()->where('authority',$authority)->first();
                if(!$find){
                    $data = [
                        'pid'=>$parentId,
                        'title'=>$config['modelShowName'].'-'.'新增',
                        'authority'=>$authority,
                        'href'=>'',
                        'is_menu'=>0,
                        'status'=>1,
                        'created_at'=>now(),
                    ];
                    Menu::query()->insert($data);
                }
            } else if($function==='update'){
                $authority = lcfirst($config['modelName']).':update';
                $find = Menu::query()->where('authority',$authority)->first();
                if(!$find){
                    $data = [
                        'pid'=>$parentId,
                        'title'=>$config['modelShowName'].'-'.'修改',
                        'authority'=>$authority,
                        'href'=>'',
                        'is_menu'=>0,
                        'status'=>1,
                        'created_at'=>now(),
                    ];
                    Menu::query()->insert($data);
                }
            } else if($function==='delete'){
                $authority = lcfirst($config['modelName']).':delete';
                $find = Menu::query()->where('authority',$authority)->first();
                if(!$find){
                    $data = [
                        'pid'=>$parentId,
                        'title'=>$config['modelShowName'].'-'.'删除',
                        'authority'=>$authority,
                        'href'=>'',
                        'is_menu'=>0,
                        'status'=>1,
                        'created_at'=>now(),
                    ];
                    Menu::query()->insert($data);
                }
            } else if($function==='detail'){
                $authority = lcfirst($config['modelName']).':detail';
                $find = Menu::query()->where('authority',$authority)->first();
                if(!$find){
                    $data = [
                        'pid'=>$parentId,
                        'title'=>$config['modelShowName'].'-'.'详情',
                        'authority'=>$authority,
                        'href'=>'',
                        'is_menu'=>0,
                        'status'=>1,
                        'created_at'=>now(),
                    ];
                    Menu::query()->insert($data);
                }
            }
        }

        $this->refreshPermission();
    }


    private function refreshPermission(){ //刷新权限表 , 使用菜单数据作为权限
        Schema::disableForeignKeyConstraints();
        DB::select("TRUNCATE permissions;");
        DB::select("insert into permissions SELECT id , pid ,title,authority as name,'admin' as guard_name,sort, created_at, updated_at FROM `menu`");
        Schema::enableForeignKeyConstraints();
    }


}
